#ifndef SPRITE_H_INCLUDED
#define SPRITE_H_INCLUDED

#include <list>
#include <vector>

namespace Oribi
{
    class Sprite
    {
    public:
        Sprite(SDL_Surface *surf = NULL);
        Sprite(SDL_Surface *s, SDL_Rect q, SDL_Point p = {0, 0});
        Sprite(const Sprite& rhs);

        virtual Sprite *clone() const;

        void blit(SDL_Surface *surf) const;
        void blitToPosition(SDL_Surface *surf, SDL_Point pos) const;
        void blitWithOffset(SDL_Surface *surf, SDL_Point offs) const;
        virtual void animate();

        SDL_Surface *sheet;
        SDL_Rect rect;
        SDL_Point position, base;

        SDL_Rect getDestRect() const;
        SDL_Point getBasePosition() const;

        SpriteAnimator *addAnimator(const SpriteAnimator&);
        void removeAnimator(SpriteAnimator*);
        void removeAndDeleteAnimator(SpriteAnimator*);

        Sprite *addChild(const Sprite&);
        void removeChild(Sprite*);

        bool operator== (const Sprite&);
    protected:
        std::list<SpriteAnimator*> animators;
        std::list<Sprite*> childSprites;
    };

    class AnimatedSprite : public Sprite
    {
    public:
        AnimatedSprite(SDL_Surface *surf = NULL);
        AnimatedSprite(SDL_Surface *s, SDL_Rect q, SDL_Point p = {0, 0});
        AnimatedSprite(const AnimatedSprite&);

        SprAnimRun *getRunningAnimation();

        void restartAnimation();
        void pauseAnimation();
        void runAnimation(int i);

        Sprite *clone() const;

        void animate();

        int  addAnimation(const SpriteAnimation& an);
        int  addAnimation(const SprAnimRun&);
        void removeAnimation(SprAnimRun*);
        void removeAndDeleteAnimation(SprAnimRun*);
    private:
        int runningAnim;
        std::vector<SprAnimRun*> animations;
        int nAnims;
    };
}

#endif // SPRITE_H_INCLUDED
